package com.yuzhitong.shapi.util;

import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;

import androidx.annotation.Nullable;

import com.yuzhitong.shapi.util.download.DownloadListener;
import com.yuzhitong.shapi.util.download.DownloadUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * FileName: DownloadService
 * Author: brsya
 * Date: 2021/1/8 14:55
 * Description: 下载服务
 */
public class DownloadService extends Service {
    private Handler handler;

    private final static List<OnReceiveMessageListener> messageListeners = new ArrayList<>();

    private DownloadInfo downloadInfo;

    private DownloadUtils downloadUtils;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        init();
    }

    private void init() {
        handler = new Handler(getMainLooper());
    }


    public static void addOnReceiveMessageListener(OnReceiveMessageListener onReceiveMessageListener) {
        messageListeners.add(onReceiveMessageListener);
    }

    public static void removeReceiveMessageListener(OnReceiveMessageListener onReceiveMessageListener) {
        messageListeners.remove(onReceiveMessageListener);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LoggerUtil.d("开启下载服务");
        int result = super.onStartCommand(intent, flags, startId);
        final String downloadUrl;
        if (intent.getStringExtra("downloadUrl") == null) {
            return result;
        }
        downloadUrl = intent.getStringExtra("downloadUrl");

        if (downloadUrl == null || downloadUrl.length() < 10) {
            return result;
        }

        LoggerUtil.d("开始下载");

        int positionTop = downloadUrl.indexOf("://") + 3;

        String urlNoTop = downloadUrl.substring(downloadUrl.indexOf("://") + 3);

        int positionSub = urlNoTop.indexOf("/") + positionTop + 1;

        String baseUrl = downloadUrl.substring(0, positionSub);

        downloadUtils = new DownloadUtils(baseUrl, new DownloadListener() {
            @Override
            public void onStartDownload() {
            }

            @Override
            public void onProgress(int progress) {
                setDownloadProgress(progress);
            }

            @Override
            public void onFinishDownload() {
                endDownload();
            }

            @Override
            public void onFail(String errorInfo) {
                error(errorInfo);
            }
        });
        downloadInfo = new DownloadInfo();

        //        downloadInfo.setSavePath(getFilesDir().getAbsolutePath() + "updateApp.apk");
        //        String tempPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/updateAppTemp " + System.currentTimeMillis() + ".apk";
        String tempPath = getFileStreamPath("updateAppTemp.apk").getAbsolutePath();
//                downloadInfo.setSavePath(getFileStreamPath("updateApp.apk").getAbsolutePath());
//                downloadInfo.setTempPath(tempPath);
        downloadInfo.setSavePath(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/updateApp.apk");
        downloadInfo.setTempPath(getFileStreamPath("updateAppTemp.apk").getAbsolutePath());
        downloadUtils.download(downloadUrl.substring(positionSub), tempPath);
        startDownload(downloadUrl);
        return result;
    }

    public void startDownload(String downloadUrl) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                for (OnReceiveMessageListener messageListener : messageListeners) {
                    if (messageListener == null) {
                        continue;
                    }
                    messageListener.startDownload(downloadUrl);
                }
            }
        });
    }

    public void setDownloadProgress(int progress) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                for (OnReceiveMessageListener messageListener : messageListeners) {
                    if (messageListener == null) {
                        continue;
                    }
                    messageListener.setDownloadProgress(progress);
                }
            }
        });
    }

    public void endDownload() {

        File file = new File(downloadInfo.getTempPath());
        File newFile = new File(downloadInfo.getSavePath());
        LoggerUtil.e("下载地址: " + newFile.getAbsolutePath());
        LoggerUtil.e("缓存地址: " + file.getAbsolutePath());
        if (newFile.exists()) {  //  确保新的文件名不存在
            if (!newFile.delete()) {
                LoggerUtil.e("文件删除失败");
                error("文件删除失败");
            }
        }
//        if (!file.renameTo(newFile)) {
//            LoggerUtil.e("文件重命名失败");
//            error("文件下载失败");
//            file.delete();
//            return;
//        }

        if (!copyFile(downloadInfo.getTempPath(), downloadInfo.getSavePath())) {
            LoggerUtil.e("文件复制失败");
            return;
        }
        handler.post(new Runnable() {
            @Override
            public void run() {
                for (OnReceiveMessageListener messageListener : messageListeners) {
                    if (messageListener == null) {
                        continue;
                    }
                    LoggerUtil.e("下载地址: " + downloadInfo.getSavePath());
                    messageListener.endDownload(downloadInfo.getSavePath());
                }
            }
        });
    }

    /**
     * 复制单个文件
     *
     * @param oldPath$Name String 原文件路径+文件名 如：data/user/0/com.test/files/abc.txt
     * @param newPath$Name String 复制后路径+文件名 如：data/user/0/com.test/cache/abc.txt
     * @return <code>true</code> if and only if the file was copied;
     * <code>false</code> otherwise
     */
    public boolean copyFile(String oldPath$Name, String newPath$Name) {
        try {
            File oldFile = new File(oldPath$Name);
            if (!oldFile.exists()) {
                LoggerUtil.e("copyFile:  oldFile not exist.");
                return false;
            } else if (!oldFile.isFile()) {
                LoggerUtil.e("copyFile:  oldFile not file.");
                return false;
            } else if (!oldFile.canRead()) {
                LoggerUtil.e( "copyFile:  oldFile cannot read.");
                return false;
            }

        /* 如果不需要打log，可以使用下面的语句
        if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) {
            return false;
        }
        */

            FileInputStream fileInputStream = new FileInputStream(oldPath$Name);    //读入原文件
            FileOutputStream fileOutputStream = new FileOutputStream(newPath$Name);
            byte[] buffer = new byte[1024];
            int byteRead;
            while ((byteRead = fileInputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, byteRead);
            }
            fileInputStream.close();
            fileOutputStream.flush();
            fileOutputStream.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public void error(String msg) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                for (OnReceiveMessageListener messageListener : messageListeners) {
                    if (messageListener == null) {
                        continue;
                    }
                    messageListener.error(msg);
                }
            }
        });
    }


    @Override
    public void onDestroy() {
        if (downloadUtils != null) {
            downloadUtils.setCompositeDisposable();
        }
        super.onDestroy();
    }


    public interface OnReceiveMessageListener {

        /**
         * 开始下载
         *
         * @param goodsId 商品id
         */
        void startDownload(String goodsId);

        /**
         * 下载进度变化
         *
         * @param progress 下载进度
         */
        void setDownloadProgress(int progress);

        /**
         * 下载完成
         *
         * @param downloadPath 商品id
         */
        void endDownload(String downloadPath);

        /**
         * 下载错误
         */
        void error(String msg);
    }


    private static class DownloadInfo {
        private String savePath;
        private String tempPath;

        public String getSavePath() {
            return savePath;
        }

        public void setSavePath(String savePath) {
            this.savePath = savePath;
        }

        public String getTempPath() {
            return tempPath;
        }

        public void setTempPath(String tempPath) {
            this.tempPath = tempPath;
        }
    }
}
